package fudan.se.lab2;

import fudan.se.lab2.domain.*;
import fudan.se.lab2.repository.*;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;

/**
 * Welcome to 2020 Software Engineering Lab2.
 * This is your first lab to write your own code and build a spring boot application.
 * Enjoy it :)
 *
 * @author LBW
 */
@SpringBootApplication
public class Lab2Application {

    public static void main(String[] args) {
        SpringApplication.run(Lab2Application.class, args);
    }

    /**
     * This is a function to create some basic entities when the application starts.
     * Now we are using a In-Memory database, so you need it.
     * You can change it as you like.
     */
    @Bean
    public CommandLineRunner dataLoader(UserRepository userRepository,
                                        AuthorityRepository authorityRepository,
                                        MeetingRepository meetingRepository,
                                        InvitationRepository invitationRepository,
                                        ContributionRepository contributionRepository
    ) {
        return new CommandLineRunner() {
            @Override
            public void run(String... args) throws Exception {
                // Create authorities if not exist.
                Authority adminAuthority = getOrCreateAuthority("Admin", authorityRepository);

                List<String> topics = new ArrayList<>();
                List<String> pcMembersFD = new ArrayList<>();
                List<String> pcMembersTJ = new ArrayList<>();
                List<String> pcMembersJT = new ArrayList<>();
                List<String> pcMembersPJW = new ArrayList<>();
                List<String> pcMembersFC = new ArrayList<>();

                String region = "shanghai";
                String wyj = "wuyanjie";
                String yzx = "yuzhexuan";
                String tzx = "taozixin";
                String sb = "somebody";
                String fdc = "FudanConference2020";
                String tjc = "TongjiConference2020";
                String sjtc = "ShanghaiJiaotongConference2020";
                String un = "UnitedNations2020";
                String spot = "New York";

                topics.add("topicA");
                topics.add("topicB");
                topics.add("topicC");

                pcMembersFD.add(wyj);
                pcMembersFD.add(yzx);
                pcMembersFD.add(tzx);
                pcMembersFD.add(sb);

                pcMembersTJ.add(yzx);
                pcMembersTJ.add(tzx);
                pcMembersTJ.add(wyj);

                pcMembersJT.add(tzx);
                pcMembersJT.add(wyj);
                pcMembersJT.add(yzx);

                pcMembersPJW.add("PJW");

                pcMembersFC.add(yzx);

                // Create an admin if not exists.
                if (userRepository.findByUsername("admin") == null) {
                    User admin = new User(
                            "admin",
                            "password",
                            "libowen",
                            "1@qq.com",
                            "fdu",
                            region,
                            new HashSet<>(Collections.singletonList(adminAuthority))
                    );
                    userRepository.save(admin);
                }

                User wuyanjie = new User(
                        wyj,
                        "20000813a",
                        wyj,
                        "wu@qq.com",
                        "fdu",
                        region,
                        new HashSet<>(Collections.singletonList(adminAuthority))
                );
                userRepository.save(wuyanjie);

                User yuzhexuan = new User(
                        yzx,
                        "20000322a",
                        yzx,
                        "yu@qq.com",
                        "fdu",
                        region,
                        new HashSet<>(Collections.singletonList(adminAuthority))
                );
                userRepository.save(yuzhexuan);

                User taozixin = new User(
                        tzx,
                        "20000602a",
                        tzx,
                        "tao@qq.com",
                        "fdu",
                        region,
                        new HashSet<>(Collections.singletonList(adminAuthority))
                );
                userRepository.save(taozixin);

                User anothorYuzhexuan = new User(
                        "yuzhexuan1",
                        "20000322a",
                        yzx,
                        "yu1@qq.com",
                        "fdu",
                        region,
                        new HashSet<>(Collections.singletonList(adminAuthority))
                );
                userRepository.save(anothorYuzhexuan);

                User pjw = new User(
                        "PJW",
                        "PJW",
                        "pjw",
                        "pjw@pjw.com",
                        "pjwu",
                        "pjwc",
                        new HashSet<>(Collections.singletonList(adminAuthority))
                );
                userRepository.save(pjw);

                User somebody = new User(
                        sb,
                        sb,
                        sb,
                        "somebody@somebody.com",
                        "somebodyU",
                        "somebodyCity",
                        new HashSet<>(Collections.singletonList(adminAuthority))
                );
                userRepository.save(somebody);

                Meeting fdc2020 = new Meeting(
                        "FDC2020",
                        fdc,
                        wyj,
                        pcMembersFD,
                        "2020-4-13",
                        "Shanghai Fudan",
                        "2020-4-11",
                        "2020-4-12",
                        2,
                        topics
                );
                meetingRepository.save(fdc2020);

                Meeting tjc2020 = new Meeting(
                        "TJC2020",
                        tjc,
                        yzx,
                        pcMembersTJ,
                        "2020-4-16",
                        "Shanghai Tongji",
                        "2020-4-14",
                        "2020-4-15",
                        1,
                        topics
                );
                meetingRepository.save(tjc2020);

                Meeting sjtc2020 = new Meeting(
                        "SJTC2020",
                        sjtc,
                        tzx,
                        pcMembersJT,
                        "2020-4-19",
                        "Shanghai Jiaotong",
                        "2020-4-17",
                        "2020-4-18",
                        2,
                        topics
                );
                meetingRepository.save(sjtc2020);

                Meeting cc2020 = new Meeting(
                        "CC2020",
                        "ComputerConference2020",
                        yzx,
                        pcMembersTJ,
                        "2020-4-22",
                        "Beijing",
                        "2020-4-20",
                        "2020-4-21",
                        1,
                        topics
                );
                meetingRepository.save(cc2020);

                Meeting tm2020 = new Meeting(
                        "TM2020",
                        "TestMeeting2020",
                        wyj,
                        null,
                        "2020-4-27",
                        "Shanghai",
                        "2020-4-25",
                        "2020-4-26",
                        -1,
                        topics
                );
                meetingRepository.save(tm2020);

                Meeting un2020 = new Meeting(
                        "UN2020",
                        un,
                        "PJW",
                        pcMembersPJW,
                        "2020-4-3",
                        spot,
                        "2020-4-1",
                        "2020-4-2",
                        1,
                        topics
                );
                meetingRepository.save(un2020);

                Meeting tc2020 = new Meeting(
                        "TC2020",
                        "TestConference2020",
                        "PJW",
                        null,
                        "2020-4-30",
                        spot,
                        "2020-4-28",
                        "2020-4-29",
                        0,
                        topics
                );
                meetingRepository.save(tc2020);

                Meeting fc2020 = new Meeting(
                        "FC2020",
                        "FinishedConference2020",
                        yzx,
                        pcMembersFC,
                        "2020-4-9",
                        spot,
                        "2020-4-4",
                        "2020-4-8",
                        5,
                        topics
                );
                meetingRepository.save(fc2020);

                Invitation invitation1 = new Invitation(
                        wyj,
                        yzx,
                        fdc,
                        1,
                        topics
                );
                invitationRepository.save(invitation1);

                Invitation invitation2 = new Invitation(
                        wyj,
                        tzx,
                        fdc,
                        1,
                        topics
                );
                invitationRepository.save(invitation2);

                Invitation invitation3 = new Invitation(
                        yzx,
                        wyj,
                        tjc,
                        1,
                        topics
                );
                invitationRepository.save(invitation3);

                Invitation invitation4 = new Invitation(
                        yzx,
                        tzx,
                        tjc,
                        1,
                        topics
                );
                invitationRepository.save(invitation4);

                Invitation invitation5 = new Invitation(
                        tzx,
                        wyj,
                        sjtc,
                        1,
                        topics
                );
                invitationRepository.save(invitation5);

                Invitation invitation6 = new Invitation(
                        tzx,
                        yzx,
                        sjtc,
                        1,
                        topics
                );
                invitationRepository.save(invitation6);

                Invitation invitation7 = new Invitation(
                        "PJW",
                        wyj,
                        un,
                        0,
                        topics
                );
                invitationRepository.save(invitation7);

                Invitation invitation8 = new Invitation(
                        "PJW",
                        yzx,
                        un,
                        0,
                        topics
                );
                invitationRepository.save(invitation8);

                Invitation invitation9 = new Invitation(
                        "PJW",
                        tzx,
                        un,
                        0,
                        topics
                );
                invitationRepository.save(invitation9);

                Invitation invitation10 = new Invitation(
                        wyj,
                        sb,
                        fdc,
                        1,
                        topics
                );
                invitationRepository.save(invitation10);

                Contribution contribution1 = new Contribution(
                        yzx,
                        fdc,
                        "yzxTitle",
                        "yzxAbstract",
                        "yzxfileName",
                        topics, null, null, null, null
                );
                contribution1.setMeetingStatus(2);
                contributionRepository.save(contribution1);

                Contribution contribution2 = new Contribution(
                        "yuzhexuan2",
                        fdc,
                        "yzxTitle2",
                        "yzxAbstract2",
                        "yzxfileName2",
                        topics, null, null, null, null
                );
                contribution2.setMeetingStatus(2);
                contributionRepository.save(contribution2);

                Contribution contribution3 = new Contribution(
                        tzx,
                        fdc,
                        "tzxTitle",
                        "tzxAbstract",
                        "tzxfileName",
                        topics, null, null, null, null
                );
                contribution3.setMeetingStatus(2);
                contributionRepository.save(contribution3);

                Contribution contribution4 = new Contribution(
                        wyj,
                        sjtc,
                        "wyjTitle",
                        "wyjAbstract",
                        "wyjfileName",
                        topics, null, null, null, null
                );
                contribution4.setMeetingStatus(2);
                contributionRepository.save(contribution4);
            }

            private Authority getOrCreateAuthority(String authorityText, AuthorityRepository authorityRepository) {
                Authority authority = authorityRepository.findByAuthority(authorityText);
                if (authority == null) {
                    authority = new Authority(authorityText);
                    authorityRepository.save(authority);
                }
                return authority;
            }
        };
    }
}
